import axios from 'axios';
import type { InternalAxiosRequestConfig, AxiosResponse, AxiosError } from 'axios';
import { message } from 'antd';
import { useUserStore } from '../store/userStore';
import { refreshToken as refreshTokenApi } from '../api/auth';
import { API_BASE_URL } from '../api/config';
import { ResponseCode } from '../types/api';
import type { ApiResponse } from '../types/api';

// 扩展AxiosRequestConfig类型
interface CustomAxiosRequestConfig extends InternalAxiosRequestConfig {
  _retry?: boolean;
}

// 创建自定义的 axios 实例
const request = axios.create({
  baseURL: API_BASE_URL,
  timeout: 10000,
  headers: {
    'Content-Type': 'application/json',
  },
});

// 是否正在刷新token
let isRefreshing = false;
// 等待刷新token的请求队列
let requests: Array<(token: string) => void> = [];

// 请求拦截器
request.interceptors.request.use(
  (config: CustomAxiosRequestConfig) => {
    // 添加时间戳，防止缓存
    if (config.method?.toLowerCase() === 'get') {
      config.params = { ...config.params, _t: Date.now() };
    }

    // 添加token
    const token = useUserStore.getState().accessToken;
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }

    return config;
  },
  (error: AxiosError) => {
    message.error('请求配置错误');
    return Promise.reject(error);
  }
);

// 响应拦截器
request.interceptors.response.use(
  (response: AxiosResponse<ApiResponse>) => {
    const { code, message: msg } = response.data;

    // 处理业务错误
    if (code !== ResponseCode.SUCCESS) {
      message.error(msg || '操作失败');
      return Promise.reject(new Error(msg));
    }

    return response;
  },
  async (error: AxiosError<ApiResponse>) => {
    const originalRequest = error.config as CustomAxiosRequestConfig;
    if (!originalRequest) {
      return Promise.reject(error);
    }

    // token过期
    if (error.response?.status === ResponseCode.UNAUTHORIZED && !originalRequest._retry) {
      if (isRefreshing) {
        // 等待token刷新
        return new Promise((resolve) => {
          requests.push((token: string) => {
            originalRequest.headers.Authorization = `Bearer ${token}`;
            resolve(request(originalRequest));
          });
        });
      }

      originalRequest._retry = true;
      isRefreshing = true;

      try {
        const refreshTokenStr = useUserStore.getState().refreshToken;
        if (!refreshTokenStr) {
          throw new Error('No refresh token');
        }

        const response = await refreshTokenApi(refreshTokenStr);
        const { accessToken } = response.data;
        
        // 更新store中的token
        useUserStore.getState().setTokens(accessToken, refreshTokenStr);
        
        // 执行队列中的请求
        requests.forEach((cb) => cb(accessToken));
        requests = [];
        
        // 重试当前请求
        originalRequest.headers.Authorization = `Bearer ${accessToken}`;
        return request(originalRequest);
      } catch (refreshError) {
        // 刷新token失败，清除用户信息并跳转到登录页
        useUserStore.getState().logout();
        message.error('登录已过期，请重新登录');
        return Promise.reject(refreshError);
      } finally {
        isRefreshing = false;
      }
    }

    // 处理其他错误
    const errorMsg = error.response?.data?.message || error.message || '网络错误';
    message.error(errorMsg);
    return Promise.reject(error);
  }
);

/**
 * GET请求
 * @param url - 请求地址
 * @param params - 请求参数
 * @param config - 额外配置
 */
export const get = async <T>(
  url: string,
  params?: Record<string, unknown>,
  config?: Partial<CustomAxiosRequestConfig>
): Promise<T> => {
  const response = await request.get<ApiResponse<T>>(url, { params, ...config });
  return response.data.data;
};

/**
 * POST请求
 * @param url - 请求地址
 * @param data - 请求数据
 * @param config - 额外配置
 */
export const post = async <T>(
  url: string,
  data?: Record<string, unknown>,
  config?: Partial<CustomAxiosRequestConfig>
): Promise<T> => {
  const response = await request.post<ApiResponse<T>>(url, data, config);
  return response.data.data;
};

/**
 * PUT请求
 * @param url - 请求地址
 * @param data - 请求数据
 * @param config - 额外配置
 */
export const put = async <T>(
  url: string,
  data?: Record<string, unknown>,
  config?: Partial<CustomAxiosRequestConfig>
): Promise<T> => {
  const response = await request.put<ApiResponse<T>>(url, data, config);
  return response.data.data;
};

/**
 * DELETE请求
 * @param url - 请求地址
 * @param config - 额外配置
 */
export const del = async <T>(
  url: string,
  config?: Partial<CustomAxiosRequestConfig>
): Promise<T> => {
  const response = await request.delete<ApiResponse<T>>(url, config);
  return response.data.data;
};

/**
 * 上传文件
 * @param url - 上传地址
 * @param file - 文件对象
 * @param config - 额外配置
 */
export const upload = async <T>(
  url: string,
  file: File,
  config?: Partial<CustomAxiosRequestConfig>
): Promise<T> => {
  const formData = new FormData();
  formData.append('file', file);
  
  const response = await request.post<ApiResponse<T>>(url, formData, {
    headers: {
      'Content-Type': 'multipart/form-data',
    },
    ...config,
  });
  
  return response.data.data;
};

export default request; 